#include "firmwareprogram.hpp"

using namespace device;
using namespace ota;
///>固件编程
firmwareprogram::firmwareprogram(flash *tFlash)
{
	mFirmWareProgramFlash = tFlash;
	CheckSumEnable = true;
}

bool firmwareprogram::Program(void)
{
	firmwaredownload::FirmWareInforTPDF tFirmWareInfor;
	uint32_t uiCheckSum = 0;
	static uint8_t ucBuff[64];
	uint32_t i, j, k;
	
	/** 读取程序信息*/
	if(mFirmWareProgramFlash == NULL)
	{
		return(false);
	}
	if(!mFirmWareProgramFlash->Read(OTA_INF_FLASH_ADDR, (uint8_t *)&tFirmWareInfor, sizeof(firmwaredownload::FirmWareInforTPDF)))
	{
		return(false);
	}
	uiCheckSum = tFirmWareInfor.uiLength + 
							 tFirmWareInfor.uiNewVersion +
							 tFirmWareInfor.uiOldVersion +
							 tFirmWareInfor.uiPackLength +
							 tFirmWareInfor.uiUpdateCount +
							 tFirmWareInfor.uiPrgCheckSum + OTA_CHECKSUM;
	if(uiCheckSum != tFirmWareInfor.uiInforCheckSum) ///> 读取程序信息
	{
		return(false);
	}
	/** 擦除APP*/
	j = APP_FLASH_SIZE;
	k = mFirmWareProgramFlash->GetSectorSize();
	j /= k;
	for(i = 0; i < j; i++)
	{
		if(!mFirmWareProgramFlash->Erase(APP_FLASH_ADDR + k * i))
		{
			return(false);
		}
	}
	/** 拷贝程序*/
	for(i = 0; i < tFirmWareInfor.uiLength;)
	{
		j = tFirmWareInfor.uiLength - i;
		if(j > 64)
		{
			j = 64;
		}
		if(!mFirmWareProgramFlash->Read(OTA_FLASH_ADDR + i, ucBuff, j))
		{
			return(false);
		}
		if(!mFirmWareProgramFlash->Write(APP_FLASH_ADDR + i, ucBuff, j))
		{
			return(false);
		}
		i += j;
	}
	if(CheckSumEnable)
	{
		/** 检验APP校验和*/
		uiCheckSum = 0;
		for(i = 0; i < tFirmWareInfor.uiLength;)
		{
			j = tFirmWareInfor.uiLength - i;
			if(j > 64)
			{
				j = 64;
			}
			if(!mFirmWareProgramFlash->Read(APP_FLASH_ADDR + i, ucBuff, j))
			{
				return(false);
			}
			for(k = 0; k < j; k++)
			{
				uiCheckSum += ucBuff[k];
			}
			i += j;
		}
		if(uiCheckSum != tFirmWareInfor.uiPrgCheckSum)
		{
			return(false);
		}
	}
	return(true);
}
